package com.health.es.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.health.es.entity.data.EsSaveDataLog;
import com.health.es.generate.GenerateExecute;
import com.health.es.temp.EsClassOperations;
import com.health.trans.common.util.GenericUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.health.es.temp.EsHelper.operations;

/**
 * 数据抽取接口添加Es数据
 *
 * @author nqlz
 */
@Slf4j
@Component
public class ConvertService {

    private static final Map<Class<?>, GenerateExecute<?>> GENERATE_EXECUTE_MAP = new ConcurrentHashMap<>();

    public ConvertService(List<GenerateExecute<?>> generateExecuteList) {
        generateExecuteList.forEach(g -> g.getTClasses().forEach(i -> GENERATE_EXECUTE_MAP.put(i, g)));
    }

    /**
     * 同步数据,默认是添加数据
     *
     * @param className 类名
     * @param object    对象
     * @return boolean
     */
    public static boolean syncData(String className, Object object) {
        return syncData(className, object, false);
    }

    public static boolean syncData(String className, Object object, boolean del) {
        boolean res = false;
        Collection<?> objectCollection;

        if (Collection.class.isAssignableFrom(object.getClass())) {
            objectCollection = (Collection<?>) object;
        } else {
            objectCollection = Collections.singletonList(object);
        }

        String simpleName = StrUtil.contains(className, ".") ? StringUtils.substringAfterLast(className, ".") : className;

        Optional<Class<?>> esClassOp = Optional.ofNullable(EsClassOperations.getEsClass(simpleName));

        if (esClassOp.isPresent()) {
            try {
                if (del) {
                    verseAndDelObjs(esClassOp.get(), objectCollection);
                } else {
                    verseAndSaveObjs(esClassOp.get(), objectCollection);
                }
                res = true;
            } catch (Exception e) {
                String msg = "Es  Json 转换错误 " + e.getMessage();
                log.error("异常：", e);
                solveError(className, simpleName, msg, objectCollection);
            }

        } else {
            String msg = className + "没有对应的实体类 Es" + simpleName;
            solveError(className, simpleName, msg, objectCollection);
        }
        return res;
    }


    /**
     * 保存当前的数据到Es ,统一处理
     *
     * @param data
     */
    private static <T> void solveError(String className, String simpleName, String msg, Collection<T> data) {
        List<EsSaveDataLog> collect = data.stream().map(i -> new EsSaveDataLog(className, simpleName, msg, i)
                .setId(IdUtil.fastUUID())).collect(Collectors.toList());
        log.error(JSONUtil.toJsonStr(collect.get(0)));
        operations.save(collect);
    }


    /**
     * 转换并保存obj节
     * 过滤 保存
     *
     * @param tClass  t类
     * @param objects 对象
     */
    public static <T> void verseAndSaveObjs(Class<T> tClass, Collection<?> objects) {
        Class<?> keyClass = GENERATE_EXECUTE_MAP.containsKey(tClass) ? tClass : Object.class;
        GENERATE_EXECUTE_MAP.get(keyClass).run(objects, GenericUtil.get(tClass));
    }

    /**
     * 转换并删除数据
     *
     * @param tClass  t类
     * @param objects 对象
     */
    public static <T> void verseAndDelObjs(Class<T> tClass, Collection<?> objects) {
        objects.stream().map(i -> GenerateExecute.executeEntity(i, tClass))
                .forEach(i -> operations.delete(i));
    }


}
